home *** CD-ROM | disk | FTP | other *** search
- /*** [tree.c]
- *
- * ディレクトリツリー情報 関連 (C)ささがわ
- *
- * For GNU C Compiler (GCC) Version 1.39
- *
- ***/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <direct.h>
- #include <dos.h>
- #include "tree.h"
- #include "others.h"
-
- #define DEFAULT_BUF 150 /* 初期のバッファサイズ */
- #define ADD_BUF 50 /* 追加バッファサイズ */
- #define DRBUFDEF 50 /* 初期のバッファサイズ */
- #define DRBUFADD 30 /* 追加バッファサイズ */
-
- static struct tree_t *trbuf;
- static int cap, nest, mnest;
- static int bufoff, bufsz;
- static int DRbuf_sz, DRbuf_err;
- static unsigned short DRbuf_tab[40], DRbuf_num[40];
- static char (*DRbuf)[13];
-
- static int (*TR_break)(void);
- static int Set_tree(void);
- static int Buf_extend(void);
- static int Set_tree_sub(void);
- static int Get_subdir(int, char *);
- static int Get_subdir_sub(int, char *);
- static int DRbuf_extend(void);
-
- /***
- * ディレクトリツリー格納関数
- * 入力: dt:ツリー情報構造体へのポインタ bt:中断用関数へのポインタ
- * 戻り値: 0 正常終了 -1 メモリーエラー -2 ディスクエラー -3 中断
- ***/
- int Get_dirtree(struct dirtree_t *dt, int c, int (*br)(void)) {
- int ret;
-
- cap = c;
- TR_break = br;
- if ((DRbuf = malloc(13 * DRBUFDEF)) == NULL) {
- DRbuf_sz = 0;
- DRbuf_err = 1;
- } else {
- DRbuf_sz = DRBUFDEF;
- DRbuf_tab[0] = 0;
- DRbuf_err = 0;
- }
-
- bufsz = DEFAULT_BUF;
- while ((ret = Set_tree()) == -4);
-
- if (ret != 0) {
- dt->tr = NULL;
- dt->numd = -1;
- dt->numc = -1;
- } else {
- int i;
- unsigned char branch[40];
-
- dt->tr = trbuf;
- dt->numd = bufoff;
- dt->numc = mnest + 1;
- for (i = 0; i < 40; i++)
- branch[i] = 0;
- for (i = 0; i < dt->numd; i++) {
- branch[trbuf[i].nest - 1] = 1;
- TR_branch(0, branch, trbuf[i].branch);
- if (trbuf[i].dirn == 0xffff)
- branch[trbuf[i].nest - 1] = 0;
- }
- }
-
- free(DRbuf);
- return ret;
- }
-
- /* バッファ格納関数 */
- static int Set_tree(void) {
- int ret;
- char dir[70];
-
- TR_bufrel();
- bufoff = 0;
- if ((trbuf = (struct tree_t *)malloc(bufsz * sizeof(struct tree_t))) == NULL)
- return -1;
-
- dir[0] = '\\';
- if (Get_curdir(0, dir + 1) || chdir("\\"))
- return -2;
-
- nest = 0;
- mnest = 0;
- trbuf[bufoff].nest = (unsigned char)nest++;
- trbuf[bufoff].dirn = 0xffff;
- strcpy(trbuf[bufoff++].name, "\\");
- ret = Set_tree_sub();
- if (ret != -2 && chdir(dir))
- return -2;
-
- return ret;
- }
-
- static int Buf_extend(void) {
- int p;
- void *buf2;
-
- p = bufsz;
- bufsz += ADD_BUF;
- if ((buf2 = malloc(bufsz * sizeof(struct tree_t))) == NULL)
- return -1;
- memcpy(buf2, trbuf, p * sizeof(struct tree_t));
- free(trbuf);
- trbuf = buf2;
-
- return 0;
- }
-
- /* ディレクトリ再帰関数 */
- /* 戻り値:0 正常終了 -4 リトライ -2 ディスクエラー -3 中断 */
- static int Set_tree_sub(void) {
- int ret, dirn = 0, p = -1;
- char buf[15];
-
- if (TR_break())
- return -3;
- while (Get_subdir(dirn, buf)) {
- p = bufoff++;
- trbuf[p].nest = (unsigned char)nest;
- trbuf[p].dirn = dirn++;
- if (!cap)
- strlow(0, (unsigned char *)buf);
- strcpy(trbuf[p].name, buf);
- if (bufoff >= bufsz) {
- if (Buf_extend())
- return -4;
- }
-
- if (chdir(buf))
- return -2;
- nest++;
- if (ret = Set_tree_sub())
- return ret;
- }
- if (TR_break())
- return -3;
-
- if (p >= 0) {
- trbuf[p].dirn = 0xffff;
- if (nest > mnest)
- mnest = nest;
- }
-
- if (nest > 1) {
- if (chdir(".."))
- return -2;
- nest--;
- }
-
- return 0;
- }
-
- /* カレントディレクトリ中のnd番目のサブディレクトリを検索する関数 */
- /* 見つかった場合はbufに格納し, 戻り値に1を返す */
- static int Get_subdir(int nd, char *buf) {
- int ret;
-
- if (nd == 0) {
- int p, err = 0;
- struct find_t ft;
-
- p = DRbuf_tab[nest - 1];
- if (!_dos_findfirst("*.*", _A_SUBDIR, &ft)) {
- if (ft.name[0] != '.' && ft.attrib & _A_SUBDIR) {
- if (p >= DRbuf_sz)
- err = DRbuf_extend();
- if (!err)
- strcpy((char *)(DRbuf + p++), ft.name);
- }
- while (!err && !_dos_findnext(&ft)) {
- if (ft.name[0] != '.' && ft.attrib & _A_SUBDIR) {
- if (p >= DRbuf_sz)
- err = DRbuf_extend();
- if (!err)
- strcpy((char *)(DRbuf + p++), ft.name);
- }
- }
- }
-
- if (err) {
- DRbuf_tab[nest] = DRbuf_tab[nest - 1];
- DRbuf_num[nest - 1] = 0xffff;
- if (Get_subdir_sub(0, buf))
- ret = 1;
- else
- ret = 0;
- } else {
- DRbuf_tab[nest] = p;
- if ((DRbuf_num[nest - 1] = DRbuf_tab[nest] - DRbuf_tab[nest - 1]) != 0) {
- strcpy(buf, DRbuf[DRbuf_tab[nest - 1]]);
- ret = 1;
- } else {
- ret = 0;
- }
- }
- } else {
- if (DRbuf_num[nest - 1] == 0xffff) {
- if (Get_subdir_sub(nd, buf))
- ret = 1;
- else
- ret = 0;
- } else if (nd > DRbuf_num[nest - 1] - 1) {
- ret = 0;
- } else {
- strcpy(buf, DRbuf[DRbuf_tab[nest - 1] + nd]);
- ret = 1;
- }
- }
-
- return ret;
- }
-
- static int Get_subdir_sub(int nd, char *buf) {
- int nd2 = 0;
- struct find_t ft;
-
- if (!_dos_findfirst("*.*", _A_SUBDIR, &ft)) {
- if (ft.name[0] != '.' && ft.attrib & _A_SUBDIR) {
- if (nd2 == nd) {
- strcpy(buf, ft.name);
- return 1;
- }
- nd2++;
- }
- while (!_dos_findnext(&ft)) {
- if (ft.name[0] != '.' && ft.attrib & _A_SUBDIR) {
- if (nd2 == nd) {
- strcpy(buf, ft.name);
- return 1;
- }
- nd2++;
- }
- }
- }
-
- return 0;
- }
-
- static int DRbuf_extend(void) {
- void *tmp;
-
- if (DRbuf_err || (tmp = malloc((DRbuf_sz + DRBUFADD) * 13)) == NULL) {
- DRbuf_err = 1;
- return -1;
- }
- memcpy(tmp, DRbuf, DRbuf_sz * 13);
- free(DRbuf);
- DRbuf = tmp;
- DRbuf_sz += DRBUFADD;
-
- return 0;
- }
-
- /* ツリー情報用バッファを開放する関数 */
- void TR_bufrel(void) {
- free(trbuf);
- trbuf = NULL;
- }
-
- void TR_branch(int mode, unsigned char *byt, unsigned char *bit) {
- int i;
-
- if (mode) {
- for (i = 0; i < 40; i++) {
- if (bit[i / 8] >> i % 8 & 1)
- byt[i] = 1;
- else
- byt[i] = 0;
- }
- } else {
- for (i = 0; i < 5; i++)
- bit[i] = 0;
- for (i = 0; i < 40; i++) {
- if (byt[i])
- bit[i / 8] += (unsigned char)(1 << i % 8);
- }
- }
- }
- int TR_Search_curd(int mode, int *curd, char *dir, struct dirtree_t *dt) {
- int ret;
-
- if (mode) {
- int n = -1, nest = 0, flag, len;
- char *ptr;
-
- ptr = strchr(dir, '\\');
- len = 1;
- do {
- int i;
-
- flag = 0;
- do {
- while (dt->tr[++n].nest != (unsigned char)nest);
- if (strncmp(ptr, dt->tr[n].name, len) == 0) {
- flag = 1;
- break;
- }
- } while (dt->tr[n].dirn != 0xffff);
- if (!flag)
- break;
-
- i = (int)strchr(ptr, '\\');
- (i == 0) ? (ptr = strchr(ptr, '\0')) : (ptr = (char *)i + 1);
- i = (int)strchr(ptr, '\\');
- (i == 0) ? (len = strlen(ptr)) : (len = (char *)i - ptr);
- nest++;
- } while (*ptr != '\0');
- if (flag) {
- ret = 1;
- *curd = n;
- } else {
- ret = 0;
- *curd = -1;
- }
- } else {
- int i, nst;
- char *p, buf[70], buf2[70];
-
- strcpy(buf, dt->tr[*curd].name);
- if (dt->tr[*curd].nest != 0)
- strcat(buf, "\\");
- nst = dt->tr[*curd].nest;
- for (i = *curd - 1; i > 0; i--) {
- if (nst <= dt->tr[i].nest)
- continue;
-
- strcat(strcat(buf, dt->tr[i].name), "\\");
- nst--;
- }
-
- strcpy(buf2, "\\");
- p = strchr(buf, '\0');
- for (i = 0; i < dt->tr[*curd].nest; i++) {
- int l;
-
- l = (int)p;
- while (--p > buf && p[-1] != '\\');
- l -= (int)p;
-
- strncat(buf2, p, l);
- }
- if (dt->tr[*curd].nest != 0)
- strchr(buf2, '\0')[-1] = '\0';
- strcpy(dir, buf2);
-
- ret = 1;
- }
-
- return ret;
- }
-